#include"BlockQueue.hpp"
#include"Task.hpp"

struct ThreadData
{
    // BlockQueue<int>* bq;
    BlockQueue<Task>* bq;
    std::string name;
};

void* consumer(void* args)
{
    ThreadData* td = static_cast<ThreadData*>(args);
    //消费者从阻塞队列中拿数据
    while(true)
    {  
        // sleep(1);//让消费者慢一点
        // int data;
        // td->bq->Pop(&data);
        //从阻塞队列中拿到任务
        Task t;
        td->bq->Pop(&t);
        t();
        t.Print();
        // std::cout << "消费者拿到了一个数据: " << data <<std::endl;
    }
    return (void*)0;
}

void* productor(void* args)
{
    ThreadData* pd = static_cast<ThreadData*>(args);
    //生产者从阻塞队列中放数据
    int data = 1;
    while(true)
    {
        sleep(1);//生产者慢一点
        // pd->bq->Enqueue(data);
        // std::cout << "生产者生产了一个数据: " <<data++ <<std::endl;
        //向阻塞队列中放任务
        int x = data;
        int y = data+1;
        Task t(x,y);
        pd->bq->Enqueue(t);//引用传参
        data++;
        std::cout << "生产者放入任务成功"  <<std::endl;
    }
}

int main()
{
    //一个交易场所为阻塞队列，需要让每一个线程看到这块空间
    // BlockQueue<int> *bp = new BlockQueue<int>();
    BlockQueue<Task> *bp = new BlockQueue<Task>();
    //主线程创建生产者、消费者模型
    pthread_t c,p;

    struct ThreadData ctd = {bp , "消费者"};
    pthread_create(&c , nullptr , consumer , (void*)&ctd);

    struct ThreadData ptd = {bp , "生产者"};
    pthread_create(&p , nullptr , productor , (void*)&ptd);

    //主线程等到所创建的新线程
    pthread_join(c , nullptr);
    pthread_join(p , nullptr);

    return 0;
}